<!-- 在线报表 -->
<template>
  <div class="report_main">
    <tabs :tabPane="tabPaneList" v-model="activeName" />
    <continer class="webchatContainer">
      <template slot="search">
        <quickSearch
          :advForm="quickSearchForm"
          @QuickSearch="headerQuery"
        ></quickSearch>
      </template>
      <template slot="oprate">
        <el-popover
          ref="popover"
          v-model="quickSearchForm.form.openPeriod"
          placement="bottom"
          width="387"
          trigger="click"
          popper-class="custom-search-pop"
          >
          <div class="query-main">
            <div class="query-title">
              <span>更多筛选</span>
            </div>
            <div class="query-content">
              <p>定时段</p>
                <el-time-select
                  placeholder="起始时间"
                  style="width: 45%"
                  v-model="quickSearchForm.form.timePeriod[0]"
                  :picker-options="{
                    start: '00:00',
                    step: '00:30',
                    end: '23:59'
                  }">
                </el-time-select>
                <div class="spacer"></div>
                <el-time-select
                  placeholder="结束时间"
                  style="width: 45%; float: right"
                  v-model="quickSearchForm.form.timePeriod[1]"
                  :picker-options="{
                    start: '00:00',
                    step: '00:30',
                    end: '24:00',
                    minTime: quickSearchForm.form.timePeriod[0]
                  }">
                </el-time-select>
              <div class="operation" >
                <el-button  type="primary" @click="toSerach(true)">检索</el-button>
              </div>
            </div>
          </div>
        </el-popover>
      <el-button slot="reference" size="mini" style="padding: 6px 12.3px"  v-popover:popover>
        <i class="V7_iconfont V7_iconV7tubiao_shaixuan"  style="font-size: 12px"></i>
        更多
      </el-button>
        <el-button type="primary" size="mini" @click="toSerach(false)">查询</el-button>
        <el-button type="primary" size="mini" @click="toSerach(false)">刷新</el-button>
        <!-- <el-button type="primary" size="mini" @click="toshow=true">测试</el-button> -->
      </template>
      <template slot="content">
        <p class="overviewOfConversation">会话整体概览</p>
        <div class="tags">
          <div v-for="i in tagList" class="tag" :key="i.name">
            <div>
              <p class="describe">{{i.name}}<br></p>
              <p class="number">{{i.value}}</p>
            </div>
          </div>
        </div>
        <p class="overviewOfConversation">时间趋势 </p>
        <div id="timeTrend"  />
        <el-popover
          ref="explainPopover"
          placement="top"
          width="500"
          trigger="hover"
          popper-class="custom-search-pop"
          >
         <div class='explainMain'>
           <p v-for="item in tableHeaders.filter(i => i.notes)" :key="item.label"><span style="color:#303753">{{item.label}}: </span><span style="color:#686E84">{{item.notes}}</span></p>
         </div>
        </el-popover>
        <p class="overviewOfConversation lh30">
          <span class="xiangqing">详情</span>
          <span class="V7_iconfont V7_iconV7tubiao_bangzhu-42  myIcon" style='color: #E0E6F0' v-popover:explainPopover></span>
          <!-- <el-button @click="jisuan(tableData, formulaList)">测试</el-button> -->
          <span class="floatRight" style="cursor: pointer;">
            <span class="slider">
              <span :class="timeState === 'second' ? 'selected':''" @click="timeStateChange('second')">秒</span>
              <span :class="timeState !== 'second' ? 'selected':''" @click="timeStateChange('HMS')">时分秒</span>
            </span>
            <!-- 表头设置 -->
            <el-dropdown trigger="click" @visible-change="headerChange">
              <span class="el-dropdown-link">
                <i title="自定义表头" class="V7_iconfont V7_iconV7tubiao_zidingyi fz14" :class="isClick? 'icon-active': ''"></i>
              </span>
              <el-dropdown-menu slot="dropdown">
                <searchCheckBox
                  :data="realHeader"
                  @check-change="handleCheckChange"
                ></searchCheckBox>
              </el-dropdown-menu>
            </el-dropdown>
            <!-- 自定义公式 -->
            <i title="自定义公式" @click="showDrawer" style="margin-left: 20px" class="V7_iconfont V7_iconV7tubiao_gongshi fz14"></i>
            <!-- 导出 -->
            <el-popover
              placement="top"
              width="100"
              trigger="click"
              popper-class="custom-search-pop"
              >
              <p style="margin-top: 6px" class='exportReport' @click="exportReport('part')">导出当前表格</p>
              <p style="margin-bottom: 6px" class='exportReport' @click="exportReport('all')">导出详细信息</p>
              <i  slot="reference" title="导出" style="margin-left: 20px" class="V7_iconfont V7_iconV7tubiao_daochu fz14"></i>
            </el-popover>
            <!-- <el-button @click="loading=true">测试</el-button> -->
          </span>
        </p>
        <!-- 表格开始 -->
        <uTable v-loading='tableLoading' :key="tableKey" v-if="tableFlag" :tableHeaders='actualHeader' :tableData="tableData"></uTable>
        <!-- 表格结束 -->
        <el-row :gutter="24" >
          <el-col :span="12">
            <p class="overviewOfConversation">首次响应时间</p>
            <div class="progressBar">
              <template v-for="item in progressBarList1">
                <p :key="item.name"><span>{{item.label}}</span><span>{{item.proportion + '%'}}</span></p>
                <el-progress :key="item.label" style="margin-bottom: 24px" :show-text='false' :stroke-width="8" :percentage="+item.proportion"></el-progress>
              </template>
            </div>
          </el-col>
          <el-col :span="12">
            <div>
             <p class="overviewOfConversation">会话时长</p>
              <div class="progressBar">
                <template v-for="item in progressBarList2">
                  <p :key="item.name"><span>{{item.label}}</span><span>{{item.proportion + '%'}}</span></p>
                  <el-progress :key="item.label" style="margin-bottom: 24px" :show-text='false' color="#69D279" :stroke-width="8" :percentage="+item.proportion"></el-progress>
                </template>
              </div>
            </div>

          </el-col>
        </el-row>
        <el-row :gutter="24" style="padding-bottom: 20px">
          <el-col :span="12">
            <p class="overviewOfConversation">渠道来源情况</p>
            <div class="overflow echartsBar" >
              <div class="grid-content  bg-purple" id="channelSources"></div>
            </div>
          </el-col>
          <el-col :span="12">
            <div >
              <p class="overviewOfConversation">满意度情况</p>
              <div class="echartsBar">
                <div class="grid-content  bg-purple-light" id="satisfaction"></div>
              </div>
            </div>
          </el-col>
        </el-row>
      </template>
    </continer>
    <!-- customFormula弹窗 -->
    <drawer
      class="import-drawer"
      direction="rtl"
      size="500px"
      :title="drawer.title"
      :drawer="drawer.isShow"
      :isShowMoreBtn = 'false'
      :wrapperClosable = 'true'
      containClass='contain'
      @save="saveCustomFormula"
      @cancelFun="cancelFun('import')"
      @closeDraw="cancelFun('import')"
    >
    <template slot="column">
      <div class="main">
        <div class="left">
          <p class="formulaList">公式列表 <span @click="addCustomFormula" class="floatRight"><i style="color: #008BEE;font-size:13px" class=" V7_iconfont V7_iconV7tubiao_xinzeng-104"></i></span></p>
          <p class="formulas" :class="item._id === selectId ? 'selected' : ''" :key="item._id" @click="selectFormula(item)" v-for="item in formulaList"><span>{{item.formulaName}}</span>
            <el-popover
              placement="top"
              width="160"
              v-model="item.visible">
              <p>确定删除吗？</p>
              <div style="text-align: right; margin: 0">
                <el-button size="mini" type="text" @click="item.visible = false">取消</el-button>
                <el-button type="primary" size="mini" @click="delCustomFormula(item)">确定</el-button>
              </div>
              <i slot="reference" class="V7_iconV7tubiao_shanchu fz12 V7_iconfont"></i>
            </el-popover>

          </p>
          <!-- <p class="formulas"><span>有效会话数</span><i class="V7_iconV7tubiao_shanchutong V7_iconfont"></i></p> -->
        </div>
        <div class="right">
          <div class="form">
            <el-form v-show="CustomFormulaShow" ref="myForm" label-position='top' :model="form" size="small" label-width="80px">
            <el-form-item label="公式名称" prop="formulaName" :rules="[{ required: true, message: '请输入', trigger: ['blur', 'change'] }]">
              <el-input v-model="form.formulaName"></el-input>
            </el-form-item>
            <el-form-item label="公式规则" prop="formulaStr" :rules="[{ required: true, message: '请输入', trigger: ['blur', 'change'] }]">
              <span slot="label">公式规则
                <el-tooltip class="item" effect="dark" placement="top">
                  <div slot="content">输入为了保证计算结果准确，请选择系统内已有的表头进行计算，当计算公式中涉及到'()/+-*'等计算符号时，<br>请输入英文键盘下对应的符号去进行运算帮助</div>
                  <span class="V7_iconfont V7_iconV7tubiao_bangzhu-42 myIcon" ></span>
                </el-tooltip>
                 </span>
              <el-input v-model="form.formulaStr"></el-input>
            </el-form-item>
            <el-form-item label="表头字段">
              <div class="uninput">
                {{headerField}}
              </div>
            </el-form-item>
            <el-form-item v-for="item in factors.filter(i=>i.state==='FACTOR' && !i.factor)" :prop="'variables.' + item.subString" :rules="[{ required: true, message: '请输入', trigger: ['blur', 'change'] }]" :key="'variables.' + item.subString" :label="item.subString">
              <el-select filterable  style="width:100%"  v-model="form.variables[item.subString]">
                <el-option
                  v-for="item in tableHeaders"
                  :key="item.prop"
                  :label="item.label"
                  :value="item.prop">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="计算结果精度">
              <el-input-number readonly  :step="1" step-strictly style="width: 100%;text-align:left" @change="presentationFormChange(form.resultDisType)" v-model="form.digits" controls-position="right" :min="0" :max="10"></el-input-number>
            </el-form-item>
            <el-form-item label="展示形式">
              <CheckBox v-model="form.resultDisType" @change="presentationFormChange">
                <CheckBoxItem label="default">默认值</CheckBoxItem>
                <CheckBoxItem label="percentage">百分比</CheckBoxItem>
              </CheckBox>
            </el-form-item>
            <el-form-item label="计算结果">
              <el-input disabled v-model="form.calculationResults" ></el-input>
            </el-form-item>
           </el-form>
          </div>
          <div class="button">
            <el-button size="mini" type="primary" v-show="CustomFormulaShow" @click="saveCustomFormula">确定</el-button>
          </div>
        </div>
      </div>
    </template>
    </drawer>
    <CustomFormula :show.sync='toshow' :formulaList='formulaList' @getCustomFormula='getCustomFormula' @saveCustomFormula='saveCustomFormula' @cancelFun='cancelFun'> </CustomFormula>
  </div>
</template>
<script lang='ts'>
import { Component, Vue, Watch } from 'vue-property-decorator'
import * as echarts from 'echarts'
import { ExportExcel } from '../../../../public/static/js/worker' // 导出
import * as formula from './base/formulaUtil' // 自定义公式相关
import drawer from '@/common/views/drawer/index.vue'
import { CommonModule } from '@/store/modules/common/index'
import {
  commonAction,
  deepClone,
  millsToDate,
  getFormatDateTime,
  isHasFuncOrMenus
} from '@/utils/common'
import tabs from '@/components/configCommon/configTabs.vue'
import customSearch from '@/views/dataCenter/callData/customSearch.vue'
import continer from '@/common/views/configCommon/ui-modules/handle-wrapper.vue'
import quickSearch from '@/common/views/advancedSearch/QuickSearch.vue'
import searchCheckBox from '@/components/configCommon/operate-modules/SearchCheckbox/index.vue'
import { uTable, CheckBox, CheckBoxItem, OtherSelect, Loading, CustomFormula } from './components/index'
import { tableHeaders } from './base/tableHeader/header'
import { selfTimeSetting } from './base/timeSetting'
function unique (val, char) { // 对象数组去重
  const list = new Map()
  return val.filter(item => !list.has(item[char]) && list.set(item[char], 1))
}
@Component({
  name: 'SessionReport',
  components: { tabs, continer, quickSearch, uTable, drawer, CheckBox, CheckBoxItem, CustomFormula, customSearch, OtherSelect, searchCheckBox, Loading }
})
export default class extends Vue {
  private $store: any
  private $getCache: any
  private loading = false
  public toshow = false
  private tabPaneList = [
    {
      label: '会话报表',
      name: 'SessionReport',
      _id: 'webchat_session_chat'
    }
  ]

  private customSearchPopopver = false
  private activeName = 'SessionReport'

  private selectId = ''

  private headers: any = []
  private getHeaders () {
    this.headers = this.tableHeaders.map(item => '#' + item.label)
    this.headerField = arr2string(this.headers)
    function arr2string (arr) {
      let result = ''
      arr.forEach(i => {
        result += i + ' '
      });
      return result
    }
  }

  private quickSearchForm: any = {
    // 快捷检索数据（时间条件，类型）
    form: {
      accessIds: [], // 接入号列表
      createTime: [
        // 创建时间 默认显示最近七天
        getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0] + ' 00:00:00',
        getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0] + ' 23:59:59'
      ],
      dimension: 'half_hour', // 维度
      openPeriod: false, // 是否开启定时间段查询
      timePeriod: [] // 开启定时间段的数据
    },
    advSearchOptions: [],
    selfPickerOptions: selfTimeSetting
  }

  private mounted () {
    this.tableLoading = true
    this.headerQuery()
    this.quickSearchForm.advSearchOptions = [
      {
        label: '会话创建时间',
        inputType: 'dateTimeRange',
        clearable: false,
        name: 'createTime'
      },
      { label: '维度', inputType: 'select', selectData: this.stateOptions, name: 'dimension' }
    ]
    this.getHeaders()
    const actionData = { url: '/im-center/action/config/satisfaction/list', method: 'POST', data: {} }
    commonAction(actionData).then(res => {
      if (res.success) {
        for (let i = 0; i < res.data.list[0].radioTagText.length; i++) {
          const element = res.data.list[0].radioTagText[i]
          this.satisfactionList[i].key = element.key
        }
        this.sessionTimeReportQuery()
      }
    })
    this.$getCache('/im-center/action/webchat/channelCache', ['channelList'], true).then(res => {
      this.channelSourcesList = []
      const list = this.$store.state.common.publicCache.channelList
      list.forEach(element => {
        element.value = 0
        this.channelSourcesList.push(element)
      })
      this.quickSearchForm.advSearchOptions.push(
        { label: '接入号', inputType: 'select', filterable: true, multiple: true, clearable: true, selectData: this.$store.state.common.publicCache.channelList, name: 'accessIds', defaultProp: { label: 'name', value: 'accessId' } }
      )
    })
  }

  private tableKey = 0
  private tableLoading = false
  private tableFlag = true
  private toSerach (flag) {
    if (flag) {
      if (!this.quickSearchForm.form.timePeriod[0] || !this.quickSearchForm.form.timePeriod[1]) {
        (this as any).$message.warning('请选择时间段')
        return
      }
    } else {
      this.quickSearchForm.form.timePeriod = []
    }
    this.tableLoading = true
    this.sessionTimeReportQuery()
    this.headerQuery()
    // setTimeout(() => {

    // }, 200);
    // this.timeStateChange()
  }

  /**
   * 表格相关
   */
  private tableHeaders = tableHeaders // 原始表头数据
  private tableData: any = []
  private basicData: any = []
  private sessionTimeReportQuery () { // 会话时间报表查询
    const flag = this.quickSearchForm.form.dimension
    commonAction({ url: '/im-report/session/time/queryData', method: 'post', data: this.quickSearchForm.form }).then(res => {
      if (res.success && res.data) {
        for (let i = 0; i < res.data.basicData.length; i++) {
          const e = res.data.basicData[i]
          this.getTime(e, flag)
        }
        this.reload(this.progressBarList1, this.progressBarList2, this.satisfactionList, this.channelSourcesList)
        if (res.data.firstResponse) {
          res.data.firstResponse.forEach(element => {
            const obj: any = this.progressBarList1.find(item => item.name === element.firstResponseLevel) || {}
            obj.value = element.firstResponseCount
          })
        }
        if (res.data.timeLength) {
          res.data.timeLength.forEach(element => {
            const obj: any = this.progressBarList2.find(item => item.name === element.sessionTimeLenLevel) || {}
            obj.value = element.sessionTimeLengthCount
          })
        }
        this.getProportion(this.progressBarList1)
        this.getProportion(this.progressBarList2)
        res.data.csr.forEach(element => {
          const obj: any = this.satisfactionList.find(item => item.key === element.satisfactionKey) || {}
          obj.value = element.satisfactionKeyCount
        })
        res.data.accessIds.forEach(element => {
          const obj: any = this.channelSourcesList.find(item => item.accessId === element.accessId) || {}
          obj.value = element.accessIdsCount
        })
        this.basicData = res.data.basicData
        const total = this.getTotal(res.data.basicData)
        setTimeout(() => {
          this.jisuan(this.basicData.concat(total), this.formulaList).then((val: any) => {
            if (!this.basicData.length) {
              val = []
            }
            this.$set(this, 'tableData', val)
            this.tableKey++
            this.tableLoading = false
            this.timeStateChange('HMS')
          })
        }, 500)
        this.drawLine()
      }
    })
  }

  private getTime (data, flag) {
    if (flag === 'half_hour') {
      let number: number | string = Math.floor((data.minuteOfDay - 1) / 2)
      if (number < 10) {
        number = '0' + number
      }
      data.time = this.newStr(data.day) + ' ' + number + ((data.minuteOfDay - 1) % 2 ? ' : 30' : ' : 00') + ' : 00'
    } else if (flag === 'hour') {
      data.time = this.newStr(data.hour)
    } else if (flag === 'day') {
      data.time = this.newStr(data.day)
    } else if (flag === 'month') {
      data.time = `${('' + data.month).slice(0, 4)}-${('' + data.month).slice(4)}`
    } else {
      data.time = data.year
    }
  }

  private newStr (str, state?) {
    str = str + ''
    const year = str.slice(0, 4)
    const month = str.slice(4, 6)
    const day = str.slice(6, 8)
    const hour = str.slice(8)
    return `${year}-${month}-${day}${hour ? ' ' + hour + ' : 00 : 00' : ''}`
  }

    private timeTrend = {
    // backgroundColor: 'rgba(236, 240, 243, 0.8)',
      legend: {
        orient: 'vertical',
        left: '20px',
        top: '30px',
        icon: 'roundRect',
        width: '300px',
        itemStyle: {
          opacity: 1
        }
      },
      tooltip: {
        trigger: 'item'
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: [],
        axisPointer: {
          show: true,
          type: 'line'
        },
        axisLabel: {}
      },
      yAxis: {
        type: 'value',
        splitLine: {
          lineStyle: {
            color: 'rgba(236, 240, 243, 0.8)',
            type: [5, 10],
            dashOffset: 5
          }
        }
      },
      grid: {
        show: true,
        backgroundColor: 'rgb(250, 252, 254)',
        borderWidth: 'none',
        left: '230px',
        right: '80px'
      },
      series: [{
        data: [820, 932, 901, 934, 1290, 1330, 1320],
        type: 'line',
        name: '猜测是',
        itemStyle: {
          opacity: 0
        },
        emphasis: {
          itemStyle: {
            opacity: 1
          }
        }
      }]
    }

  private tagList = [
    { name: '会话总数', prop: 'initCount', value: '0' },
    { name: '有效会话数', prop: 'validCount', value: '0' },
    { name: '机器人会话数', prop: 'robotCount', value: '0' },
    { name: '人工服务数', prop: 'manualCount', value: '0' },
    { name: '总消息数', prop: 'msgCount', value: '0' },
    { name: '排队数', prop: 'queueUpCount', value: '0' },
    { name: '排队放弃数', prop: 'queueGiveUpCount', value: '0' },
    { name: '留言数', prop: 'leavingCount', value: '0' },
    { name: '流失会话数', prop: 'lossCount', value: '0' },
    { name: '完成会话数', prop: 'finishCount', value: '0' }
  ]

  private totalToTags () {
    for (let i = 0; i < this.tagList.length; i++) {
      const element = this.tagList[i]
      element.value = this.total[element.prop] || '0'
    }
  }

  private timeTrendList: any = []
  private tagsToEcharts () {
    this.timeTrendList = []
    for (let i = 0; i < this.tagList.length; i++) {
      const e = this.tagList[i]
      const data = []
      this.timeTrendList.push({
        data: [],
        // showSymbol: false,
        type: 'line',
        smooth: true,
        name: e.name,
        prop: e.prop,
        areaStyle: {
          opacity: 0.1
        },
        emphasis: {
          itemStyle: {
            opacity: 1
          }
        },
        itemStyle: {
          opacity: 0
        }
      })
    }
    this.basicData.forEach(element => {
      this.timeTrendList.forEach(val => {
        val.data.push(element[val.prop])
      })
    })
  }

  private async headerQuery () { // 表头查询
    const url = '/im-center/action/report/header/query'
    const data = { type: 'session' }
    await commonAction({ url, method: 'post', data }).then(res => {
      this.otherHeaders = res.data.config
      this.getCustomFormula()
    })
  }

  private headerChange (val) { // 表头修改
    if (!val) {
      const url = '/im-center/action/report/header/update'
      this.actualHeader.forEach(element => {
        if (element.prop.includes('-')) {
          element.isCustomHeader = true
        } else {
          element.isCustomHeader = false
        }
      });
      const data = { type: 'session', config: this.actualHeader }
      commonAction({ url, method: 'post', data }).then(res => {
        this.headerQuery()
      })
    }
  }

  private headerInit (arr) {
    const flag = arr.find(i => i.prop === 'time')
    if (!flag) {
      arr.unshift({ label: '时间', prop: 'time', show: true, width: '200' })
    }
    this.$set(this, 'actualHeader', arr)
  }

  get realHeader () {
    let arr: any = []
    arr = [...this.otherHeaders].concat(this.customFormulaHeader)
    arr = unique(arr, 'prop')
    return arr
  }

  set realHeader (arr) {
    //
  }

  private actualHeader: any = [{}] // 真实表头
  private otherHeaders: any = tableHeaders // 表头配置
  private handleCheckChange (arr) { //
    this.headerInit([...arr])
    // this.headerChange()
  }

  private total = {}
  private getTotal (arr) { // 求合计
    const total = Object.assign({}, arr[0])
    for (let i = 1; i < arr.length; i++) {
      const element = arr[i]
      for (const key in total) {
        if (isNaN(element[key])) {
          //
        } else {
          total[key] += Number(element[key])
        }
      }
    }
    let number: any = Number(total.sessionTimeLen / total.finishCount)
    if (isNaN(number)) {
      number = 0
    }
    number = number.toFixed(0)
    total.sessionTimeLen = '--'
    total.time = '总计'
    total.flag = '总计'
    this.total = total
    this.totalToTags()
    return total
  }

  private stateOptions: object[] = [
    { name: '半小时', _id: 'half_hour' },
    { name: '一小时', _id: 'hour' },
    { name: '一天', _id: 'day' },
    // { name: '周', _id: 'week' },
    { name: '月', _id: 'month' },
    { name: '年', _id: 'year' }
  ]

  // 自定义公式相关
  private drawer = {
    title: '配置自定义公式',
    isShow: false
  }

  private headerField: any = []

  private cancelFun () {
    this.drawer.isShow = false
    this.CustomFormulaShow = false
    this.addCustomFormulaFlag = false
    this.selectId = ''
    this.form = {
      variables: {}
    }
  }

  private showDrawer () {
    this.drawer.isShow = true
    this.getCustomFormula()
  }

  private CustomFormulaShow = false
  private formulaList: any = [] // 自定义公式列表
  private addCustomFormulaFlag = false
  private addCustomFormula () {
    this.CustomFormulaShow = true
    if (this.addCustomFormulaFlag) {
      (this as any).$message.warning('您正在添加的公式尚未保存, 请勿重复添加')
    } else {
      this.addCustomFormulaFlag = true
      this.selectId = ''
      this.form = {
        formulaName: '',
        formulaStr: '',
        digits: '',
        calculationResults: '',
        resultDisType: 'default',
        variables: {},
        formulaType: 'session_report'
      };
      setTimeout(() => {
        (this.$refs.myForm as any).clearValidate()
      }, 0);
    }
  }

  private selectFormula (item) {
    this.selectId = item._id
    this.addCustomFormulaFlag = false
    this.CustomFormulaShow = true
    this.$set(this, 'form', item)
  }

  private saveCustomFormula () {
    (this.$refs.myForm as any).validate(valid => {
      if (valid) {
        const url = '/im-report/formula/addUpdate'
        const data = this.form
        commonAction({ url, method: 'post', data }).then(res => {
          if (res.success) {
            (this as any).$message.success(this.addCustomFormulaFlag ? '添加成功' : '修改成功')
            this.drawer.isShow = false
            this.addCustomFormulaFlag = false
            this.CustomFormulaShow = false
            this.selectId = ''
            this.getCustomFormula(true)

            this.form = {
              variables: {}
            }
          }
        })
      }
    })
  }

  private delCustomFormula (val) {
    const url = '/im-report/formula/remove'
    const data = { _id: val._id }
    commonAction({ url, method: 'post', data }).then(res => {
      if (res.success) {
        (this as any).$message.success('删除成功')
        val.visible = false
        this.getCustomFormula()
        this.CustomFormulaShow = false
        this.selectId = ''
        this.factors = [{}]
        this.form = {}
      }
    })
  }

  private customFormulaHeader: any = [{}]
  private getCustomFormula (flag?: boolean) {
    const url = '/im-report/formula/getList'
    const data = { formulaType: 'session_report' }
    commonAction({ url, method: 'post', data }).then(res => {
      if (res.success) {
        this.$set(this, 'formulaList', res.data)
        this.getCustomFormulaHeader(this.formulaList)
        for (let i = 0; i < this.otherHeaders.length; i++) {
          const element = this.otherHeaders[i]
          if (element.isCustomHeader) {
            if (!this.formulaList.find(item => item._id === element.prop)) {
              this.otherHeaders.splice(i, 1)
              i--
            }
          }
        }
        this.customFormulaHeader.forEach(element => {
          if (!this.otherHeaders.find(item => item.prop === element.prop)) {
            this.otherHeaders.push(element)
          } else {
            const val = this.otherHeaders.find(item => item.prop === element.prop)
            val.label = element.label
          }
        })
        this.headerInit(this.otherHeaders)
        if (flag) {
          this.tableLoading = true
          this.jisuan(this.tableData, this.formulaList).then(val => {
            this.$set(this, 'tableData', val)
            this.tableLoading = false
            this.tableKey++
          })
        }
      }
    })
  }

  private getCustomFormulaHeader (arr: any[]) {
    const list: any = []
    arr.forEach(item => {
      let flag = false
      for (const key in item.variables) {
        if (item.variables[key] === 'sessionTimeLen') {
          flag = true
        }
      }
      list.push({
        label: item.formulaName,
        prop: item._id,
        width: 120,
        show: true,
        isCustomHeader: true,
        formulaStr: item.formulaStr,
        variables: item.variables,
        digits: item.digits,
        HMS: flag
      })
    })
    this.customFormulaHeader = list
  }

  private userDefinedFormulaCalculation (val) {
    const result = formula.parseFormulaStr(val)
    const result2 = Number(formula.evalRpn(formula.dal2Rpn(result))?.value).toFixed(this.form.digits)
  }

  private jisuan (data, formulas) {
    return new Promise((resolve, reject) => {
      const total = {}
      formulas.forEach(eq => { total[eq._id] = 0 })
      data.forEach(item => {
        for (let i = 0; i < formulas.length; i++) {
          const e = formulas[i]
          try {
            const parseResult = formula.parseFormulaStr(e.formulaStr)
            parseResult.forEach(s => {
              if (!isNaN(s.subString)) {
                s.factor = '_const'
              }
            })
            const rpns = formula.dal2Rpn(parseResult)
            const result = formula.evalRpn(rpns, e.variables, item)
            console.log(rpns, e.variables, item, 123123)
            item[e._id] = getValue(result.value, e.digits, e.resultDisType)
            const reg = /\/[^0-9]/
            if (reg.test(e.formulaStr)) {
              if (item.flag === '总计') {
                total[e._id] = '--'
              }
            } else {
              if (item.flag !== '总计') {
                total[e._id] += result.value
              }
            }
          } catch {
            //
          }
        }
      })
      formulas.forEach(es => {
        if (!es.formulaStr.includes('/')) {
          total[es._id] = getValue(total[es._id], es.digits, es.resultDisType)
        }
      })
      for (let i = 0; i < data.length; i++) {
        const element = data[i];
        if (element.flag === '总计') {
          for (const key in total) {
            const val = total[key];
            data[i][key] = val
          }
        }
      }
      resolve(data)
    })
    function getValue (val, digits, resultDisType) {
      if (!isNaN(Number(val))) {
        if (resultDisType === 'default') {
          return Number(Number(val).toFixed(digits))
        } else {
          return (Number(val * 100).toFixed(digits)) + '%'
        }
      } else {
        return 0
      }
    }
  }

  private factors: any = [{}]
  private form: any = {
    formulaName: '',
    formulaStr: '',
    digits: '',
    calculationResults: '',
    resultDisType: '',
    variables: {},
    formulaType: 'session_report'
  }

  private resultStorage = ''
  @Watch('form.formulaStr')
  private ruleChange (val) {
    try {
      // this.form.variables = {}
      const result = formula.parseFormulaStr(val)
      this.factors = unique(result, 'subString')?.map(item => {
        // this.$set(this.form.variables, item.subString, '')
        if (!isNaN(item.subString)) {
          item.factor = '_const'
        }
        return item
      }) || [{}]
      const xresult = formula.evalRpn(formula.dal2Rpn(result))
      if (xresult && xresult.state === 'FACTOR') {
        this.form.calculationResults = Number(1).toFixed(this.form.digits)
      } else {
        if (isNaN(xresult?.value)) {
          this.form.calculationResults = '计算有误'
        } else {
          this.form.calculationResults = Number(xresult?.value).toFixed(this.form.digits)
        }
      }
      this.resultStorage = this.form.calculationResults
    } catch (error) {
      //
    }
  }

  private accuracyBlur () {
    this.form.calculationResults = Number(this.resultStorage).toFixed(this.form.digits)
  }

  private presentationFormChange (val) {
    if (val === 'default') {
      this.form.calculationResults = Number(this.resultStorage).toFixed(this.form.digits)
    } else {
      this.form.calculationResults = this.toPercent(this.resultStorage)
    }
  }

  private toPercent (point) {
    let str = Number(point * 100).toFixed(this.form.digits)
    str += '%'
    return str
  }

  // 图表相关
  private progressBarList1 = [
    { label: '>1m', name: 5, value: 0, proportion: 0 },
    { label: '45s-1m', name: 4, value: 0, proportion: 0 },
    { label: '30s-45s', name: 3, value: 0, proportion: 0 },
    { label: '15s-30s', name: 2, value: 0, proportion: 0 },
    { label: '<15s', name: 1, value: 0, proportion: 0 }
  ]

  private progressBarList2 = [
    { label: '>8m', name: 5, value: 0, proportion: 0 },
    { label: '6m-8m', name: 4, value: 0, proportion: 0 },
    { label: '4m-6m', name: 3, value: 0, proportion: 0 },
    { label: '2m-4m', name: 2, value: 0, proportion: 0 },
    { label: '<2m', name: 1, value: 0, proportion: 0 }
  ]

  private reload (...arr) {
    arr.forEach(element => {
      element.forEach(item => {
        item.value = 0
        // eslint-disable-next-line no-prototype-builtins
        if (item.hasOwnProperty('proportion')) {
          item.proportion = 0
        }
      })
    })
  }

  private getProportion (arr) {
    let total = 0
    arr.forEach(element => {
      total += element.value
    })
    if (total === 0) {
      arr.forEach(i => {
        i.proportion = 0
      })
      return
    }
    arr.forEach(item => {
      if (item.value === 0) {
        item.proportion = 0
      } else {
        item.proportion = Number((item.value / total) * 100).toFixed(0)
      }
    })
  }

  private qiuhe (arr) {
    let result = 0
    for (let i = 0; i < arr.length; i++) {
      const element = arr[i]
      result += element
    }
    return result
  }

  private resizeWidth: number = 300
  private drawLine () {
    this.resizeWidth = document.querySelector('.header-contain')?.scrollWidth || 300
    this.timeTrend.xAxis.data = this.basicData.map(item => item.time)
    if (this.basicData.length > 7) {
      this.timeTrend.xAxis.axisLabel = {
        rotate: 15
      }
    }
    this.tagsToEcharts()
    this.timeTrend.series = this.timeTrendList
    this.satisfactionOption.series[0].data = this.satisfactionList
    this.channelSourcesOption.series[0].data = this.channelSourcesList
    this.channelSourcesOption.legend.formatter = params => {
      let name = params
      if (params.length > 10) {
        name = params.slice(0, 10) + '...'
      }
      const dataAll = this.channelSourcesList.map(item => Number(item.value))
      const total = this.qiuhe(dataAll)
      const value = Number(this.channelSourcesList.filter(item => item.name === params)[0]?.value)
      if (total === 0) {
        return `${name} 0 0.00%`
      }

      return `${name} ${value}个 (${((value * 100) / total).toFixed(2)}%)`
    }
    this.satisfactionOption.legend.formatter = params => {
      const dataAll = this.satisfactionList.map(item => Number(item.value))
      const total = this.qiuhe(dataAll)
      const value = Number(this.satisfactionList.filter(item => item.name === params)[0]?.value)
      if (total === 0) {
        return `${params} 0 0.00%`
      }
      const name = params
      return `${name} ${value}个 (${((value * 100) / total).toFixed(2)}%)`
    }
    const width = this.resizeWidth / 2 - 20
    if (width < 570) {
      this.channelSourcesOption.series[0].right = '70%'
      this.satisfactionOption.series[0].right = '70%'
    }
    this.drawCharts('#timeTrend', this.timeTrend, { width: this.resizeWidth, height: 300 })
    this.drawCharts('#channelSources', this.channelSourcesOption, { width, height: 290 })
    this.drawCharts('#satisfaction', this.satisfactionOption, { width, height: 290 })
    // this.drawFirstResponseTime()
  }

  /**
   * 绘图方法
   */
  private drawCharts (dom, option, setting = {}) {
    const node = document.querySelector(dom)
    let myChart = echarts.getInstanceByDom(node)
    if (!myChart) {
      myChart = echarts.init(node, '', setting)
    }
    myChart.setOption(option)
  }

  private channelSourcesList: any = []
  // 渠道来源情况
  private channelSourcesOption: any = {
    tooltip: {
      trigger: 'item'
    },
    legend: {
      top: 'middle',
      height: '50%',
      right: '0%',
      orient: 'vertical',
      type: 'scroll',
      formatter: '{d}%',
      tooltip: {
        show: true
      }
    },
    series: [
      {
        name: '渠道来源情况',
        type: 'pie',
        stillShowZeroSum: false,
        left: '20',
        right: '30%',
        radius: ['70%', '95%'],
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: true,
            fontSize: '16',
            fontWeight: 'bold'
          }
        },
        labelLine: {
          show: false
        },
        data: [
          { value: 1048, name: '搜索引擎' },
          { value: 735, name: '直接访问' },
          { value: 580, name: '邮件营销' },
          { value: 484, name: '联盟广告' },
          { value: 300, name: '视频广告' }
        ]
      }
    ]
  }

  private satisfactionOption: any = {
    tooltip: {
      trigger: 'item'
    },
    legend: {
      top: 'middle',
      right: '20',
      orient: 'vertical',
      type: 'scroll'
    },
    series: [
      {
        name: '满意度情况',
        type: 'pie',
        stillShowZeroSum: false,
        left: '20',
        right: '30%',
        radius: ['70%', '95%'],
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: true,
            fontSize: '16',
            fontWeight: 'bold'
          }
        },
        labelLine: {
          show: false
        },
        data: [
          { value: 1048, name: '搜索引擎' },
          { value: 735, name: '直接访问' },
          { value: 580, name: '邮件营销' },
          { value: 484, name: '联盟广告' },
          { value: 300, name: '视频广告' }
        ]
      }
    ]
  }

  private satisfactionList = [
    { name: '非常满意', id: 5, value: 0, key: '' },
    { name: '满意', id: 4, value: 0, key: '' },
    { name: '一般', id: 3, value: 0, key: '' },
    { name: '不满意', id: 2, value: 0, key: '' },
    { name: '非常不满意', id: 1, value: 0, key: '' }
  ]

  private select: string[] = []
  private selectChange (val, obj) {
    console.log(val, obj)
    // if (this.select.includes(val.label)) {
    //   this.select.splice(this.select.indexOf(val.label), 1)
    // } else {
    //   this.select.push(val.label)
    // }
    // obj.checked = !val.checked
  }

  private exportReport (val) {
    const header = this.actualHeader
    const tableData = this.tableData
    const year = new Date().getFullYear() + ''
    const month = new Date().getMonth() + 1 + ''
    const day = new Date().getDay() + ''
    const time = `${year}${month}${day}`
    const name = `${time}-${this.$store.state.common.session.user.agentName || ''}-会话报表`
    if (val === 'all') {
      const de = new ExportExcel(header, tableData)
      de.toExport(name)
    } else {
      const de = new ExportExcel(header.filter(item => item.show), tableData)
      de.toExport(name)
    }
  }

  private getSatisfactionList () {
    //
  }

  // timeConversion
  private isClick = false
  private timeState = 'second' // 时分秒: HMS
  private timeStateChange (val, data?: any) {
    const list = this.customFormulaHeader.filter(item => item.HMS)
      .map(i => i.prop)
    const timeTransformation = require('./base/timeConversion')
    this.timeState = val
    if (val === 'second') {
      this.tableData.forEach(element => {
        element.sessionTimeLen = timeTransformation.formatHSM(element.sessionTimeLen)
        list.forEach(r => {
          element[r] = timeTransformation.formatHSM(element[r])
          // console.log(456, element[r])
        })
      });
    } else {
      this.tableData.forEach(element => {
        element.sessionTimeLen = timeTransformation.formatSeconds(element.sessionTimeLen)
        list.forEach(r => {
          element[r] = timeTransformation.formatSeconds(element[r])
          // console.log(123, element[r])
        })
      })
    }
    this.tableKey++
  }
}
</script>
<style lang='stylus' scoped>
@import './css/index.styl'

</style>
<style lang='stylus'>
.mySelect
  .el-scrollbar__view
    display: flex;
    flex-wrap: wrap;
    width: 190px;
.jinx
  .el-checkbox__inner
    background-color: #fff!important
    border-color: #DCDFE6
    cursor: pointer!important
.custom-search-pop
  padding 0
  min-width unset
.reportTable:last-child
  font-weight: 600
  color #686E84
  .time
    div
      font-family: PingFang SC;
      color: #008BEE;
.spacer
  display inline-block
  width: 10px;
  background: #ccc;
  height: 3px;
  margin-left: 13px;
  vertical-align: middle;
.uninput
  background: #F3F6F9;
  border: 1px solid #E7E9ED;
  border-radius: 4px;
  padding 10px
</style>
